/**
 * Copyright (C) 2025 pony working team
 * SPDX-License-Identifier: MulanPSL-2.0
 */

#include <gtest/gtest.h>

#include <stdio.h>

#include "x_printf.h"

extern "C" {

static int my_putc(uintptr_t arg, unsigned char ch)
{
    if (ch == '\n') {
        putchar('\r');
    }
    putchar(ch);

    return 1;
}

int my_printf(const char *format, ...)
{
    va_list valist;
    int nbytes;

    va_start(valist, format);
    nbytes = xprintf(format, valist, my_putc, 0);
    va_end(valist);

    return nbytes;
}
}

class TestPrintf : public ::testing::Test
{
protected:
    void SetUp() {};

    void TearDown() {};
};

TEST_F(TestPrintf, xprintf)
{
    my_printf("hello pony\n");
    my_printf("%");   // print nothing
}

TEST_F(TestPrintf, xprintf_d)
{
    my_printf("%d\n", 123);
    my_printf("%d\n", -123);

    my_printf("%ld\n", 123);
    my_printf("%ld\n", -123);

    my_printf("%lld\n", 123);
    my_printf("%lld\n", -123);

    my_printf("%d\n", 0);
}

TEST_F(TestPrintf, xprintf_u)
{
    my_printf("%u\n", 123);
    my_printf("%lu\n", 123);
    my_printf("%llu\n", 123);
}

TEST_F(TestPrintf, xprintf_x)
{
    my_printf("%x\n", 0x123);
}

TEST_F(TestPrintf, xprintf_X)
{
    my_printf("%X\n", 0x123);
}

TEST_F(TestPrintf, xprintf_s)
{
    my_printf("%s\n", "pony");
}

TEST_F(TestPrintf, xprintf_c)
{
    my_printf("%c\n", 'p');
    my_printf("%c\n", '\n');
}

TEST_F(TestPrintf, xprintf_p)
{
    my_printf("%p\n", (void *)0x123);
}

TEST_F(TestPrintf, xprintf_width)
{
    my_printf("%5d\n", 123);
    my_printf("%-5d\n", 123);
    my_printf("%05d\n", 123);
    my_printf("%5s\n", "pony");
    my_printf("%-5s\n", "pony");
    my_printf("%05s\n", "pony");
    my_printf("%5c\n", 'p');
    my_printf("%-5c\n", 'p');
    my_printf("%05c\n", 'p');
    my_printf("%5p\n", (void *)0x123);
    my_printf("%-5p\n", (void *)0x123);
    my_printf("%05p\n", (void *)0x123);
    my_printf("%5u\n", 123);
    my_printf("%-5u\n", 123);
    my_printf("%05u\n", 123);
    my_printf("%5x\n", 0x123);
    my_printf("%-5x\n", 0x123);
    my_printf("%05x\n", 0x123);
    my_printf("%5X\n", 0x123);
    my_printf("%-5X\n", 0x123);
    my_printf("%05X\n", 0x123);

    my_printf("%11d\n", 123456789);
}

TEST_F(TestPrintf, xprintf_plus)
{
    my_printf("%+d\n", 123);
    my_printf("%+d\n", -123);
}

TEST_F(TestPrintf, xprintf_star)
{
    my_printf("%*d\n", 5, 123);
    my_printf("%*d\n", -5, 123);
}

TEST_F(TestPrintf, xprintf_percent)
{
    my_printf("%%\n");
}

TEST_F(TestPrintf, xprintf_unsupported)
{
    my_printf("%a\n");
}
